// 组件: zj-select 普通选择器 (底部弹出)
// https://developers.weixin.qq.com/miniprogram/dev/component/picker.html
// ==================== 参数 ====================
// ※ value ==> 当前值
// ※ model ==> 双向绑定时父组件的键名
// ※ options ==> 数据列表 (默认: [])
// ※ valKey ==> 当数据列表为 Object Array 时, 当前值的键名 (默认: 'id')
// ※ labKey ==> 当数据列表为 Object Array 时, 显示值的键名 (默认: 'name')
// ※ placeholder ==> 提示文字 (默认: '请选择')
// ※ clearable ==> 是否可清除 (默认: true)
// ※ disabled ==> 是否禁用 (默认: false)
// ※ data ==> 数据, 仅做传递使用
// ※ error ==> 错误验证(当前值&提示信息 字体变红) (默认: false)
// ==================== 事件 ====================
// ※ bind:model="model(e)" ==> 双向绑定
// ※ bind:change="change(e)" ==> 选择器值改变时
// ※ bind:clear="clear(e)" ==> 清除事件
// ==================== 插槽 slot ====================
// ※ 默认插槽 ==> xxxxx
// ※ xxxxx ==> xxxxx
// ==================== 方法 ====================
// ※ xxxxx ==> xxxxx

Component({
  properties: {
    value: { // 当前值
      type: String
    },
    model: { // 双向绑定时父组件的键名
      type: String
    },
    options: { // 数据列表
      type: Array,
      value: []
    },
    valKey: { // 当数据列表为 Object Array 时, 当前值的键名
      type: String,
      value: 'id'
    },
    labKey: { // 当数据列表为 Object Array 时, 显示值的键名
      type: String,
      value: 'name'
    },
    placeholder: { // 提示文字
      type: String,
      value: '请选择'
    },
    clearable: { // 是否可清除
      type: Boolean,
      optionalTypes: [String, Number, Boolean],
      value: true
    },
    disabled: { // 是否禁用
      type: Boolean
    },
    data: { // 数据, 仅做传递使用
      type: String, // 没用, 这个设定太弱智了
      optionalTypes: [String, Number, Boolean, Object, Array]
    },
    error: { // 错误验证
      type: Boolean,
      value: false
    }
  },
  data: {
    ind: null, // 当前索引
    // ========== 判断 ==========
    judge_isObj: false, // options[0]是否为object
    judge_placeholderIsShow: false // placeholder是否显示
  },
  observers: {
    // ========== 监听'当前值', 判断placeholder是否显示 ==========
    'value': function (value) {
      const ind = this.findIndex(this.properties.value)
      this.setData({
        ind,
        judge_placeholderIsShow: Boolean(!value && value !== 0)
      })
    },
    // ========== 监听'options', options[0]是否为object ==========
    'options': function (options) {
      this.setData({
        judge_isObj: Boolean(typeof(options[0]) === 'object'),
        value: this.properties.value
      })
    }
  },
  methods: {
    // ========== 数组找下标 ==========
    findIndex (val) {
      const options = this.properties.options
      const valKey = this.properties.valKey
      let result = null
      if (this.data.judge_isObj) {
        result = options.findIndex(b => b[valKey] === val || b[valKey] + '' === val + '')
      } else {
        result = options.findIndex(b => b === val || b + '' === val + '')
      }
      return result
    },
    // ========== 选择器值改变时 ==========
    change (e) {
      const ind = e.detail.value * 1
      this.setData({ ind: ind })
      // 获取当前值
      const options = this.properties.options
      const valKey = this.properties.valKey
      const judge_isObj = this.data.judge_isObj
      e.currentTarget.dataset.index = ind
      e.currentTarget.dataset.item = options[ind]
      e.detail.value = judge_isObj ? options[ind][valKey] : options[ind]
      this.triggerEvent('model', e)
      this.triggerEvent('change', e)
    },
    // ========== 取消点击事件 ==========
    cancel () {
      if (this.properties.clearable) this.clear()
    },
    // ========== 清除 ==========
    clear () {
      this.setData({ isFocus: true })
      const e = {
        currentTarget: { dataset: { model: this.properties.model } },
        detail: { value: '' }
      }
      this.triggerEvent('model', e)
      this.triggerEvent('clear', e)
      this.triggerEvent('change', e)
    }
  }
})
